#include "avro_napi.h"
#include "../utils/ohoslog/ohos_log.h"
#include "native_common.h"

static napi_ref g_constructor_ref = nullptr;

napi_value Parse(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value argv[1];
    napi_value jsthis;
    napi_status status = napi_get_cb_info(env, info, &argc, argv, &jsthis, nullptr);
    if (status != napi_ok) {
        LOGERROR("napi_get_cb_info failed!");
        return nullptr;
    }

    // 拿到之前注册好的 constructor
    napi_value ctor;
    status = napi_get_reference_value(env, g_constructor_ref, &ctor);
    if (status != napi_ok) {
        LOGERROR("napi_get_reference_value failed!");
        return nullptr;
    }

    napi_value instance;
    status = napi_new_instance(env, ctor, argc, argv, &instance);
    if (status != napi_ok || instance == nullptr) {
        LOGERROR("napi_new_instance failed!");
        return nullptr;
    }

    // 判断创建AvroTypeC类实例是否成功
    if (!g_IsParseSuccess) {
        LOGERROR("create AvroTypeC class failed!");
        return nullptr;
    }

    return instance; // 返回创建的实例
}

EXTERN_C_START
napi_value Init(napi_env env, napi_value exports) {
    // 绑定toBuffer方法到类原型
    napi_value prototype;
    napi_get_prototype(env, exports, &prototype);
    napi_property_descriptor desc[] = {DECLARE_NAPI_FUNCTION("toBuffer", AvroTypeC::ToBuffer),
                                       DECLARE_NAPI_FUNCTION("getName", AvroTypeC::GetSchemaTypeName),
                                       DECLARE_NAPI_FUNCTION("getArrayItemType", AvroTypeC::GetArrayItemType),
                                       DECLARE_NAPI_FUNCTION("getMapValueType", AvroTypeC::GetMapValueType),
                                       DECLARE_NAPI_FUNCTION("getFixedSize", AvroTypeC::GetFixedSize),
                                       DECLARE_NAPI_FUNCTION("getSchema", AvroTypeC::GetSchema),
                                       DECLARE_NAPI_FUNCTION("getAliases", AvroTypeC::GetAliases),
                                       DECLARE_NAPI_FUNCTION("fromBuffer", AvroTypeC::FromBuffer),
                                       DECLARE_NAPI_FUNCTION("isValid", AvroTypeC::IsValid),
                                       DECLARE_NAPI_FUNCTION("compareBuffers", AvroTypeC::CompareBuffers),
                                       DECLARE_NAPI_FUNCTION("compare", AvroTypeC::Compare)};
    napi_value cons;
    napi_define_class(env, "AvroTypeC", NAPI_AUTO_LENGTH, AvroTypeC::Construct, nullptr, sizeof(desc) / sizeof(*desc),
                      desc, &cons);
    napi_define_properties(env, prototype, sizeof(desc) / sizeof(desc), desc);

    // 保存 constructor 引用，供 CreateInstance 用
    napi_create_reference(env, cons, 1, &g_constructor_ref);

    // 导出parse函数作为模块方法
    napi_property_descriptor descparse[] = {
        {"parse", nullptr, Parse, nullptr, nullptr, nullptr, napi_default, nullptr},
    };
    napi_define_properties(env, exports, sizeof(descparse) / sizeof(descparse), descparse);

    napi_value serializeToFileFunc;
    napi_create_function(env, "toFile", NAPI_AUTO_LENGTH, SerializeToFile, nullptr, &serializeToFileFunc);
    napi_set_named_property(env, exports, "toFile", serializeToFileFunc);

    napi_value fromFileFunc;
    napi_create_function(env, "fromFile", NAPI_AUTO_LENGTH, FromFile, nullptr, &fromFileFunc);
    napi_set_named_property(env, exports, "fromFile", fromFileFunc);

    return exports;
}
EXTERN_C_END


static napi_module avroModule = {
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = Init,
    .nm_modname = "avro_napi",
    .nm_priv = ((void *)0),
    .reserved = {0},
};

extern "C" __attribute__((constructor))
void RegisterEntryModule(void) {
    napi_module_register(&avroModule);
}